﻿using System;
using System.Globalization;
using System.Text.RegularExpressions;

namespace Xenta.Utils
{
    /// <summary>
    /// Represents the numeric helper.
    /// </summary>
    public static class NumericHelper
    {
        /// <summary>
        /// Converts the decimal value to a string representation.
        /// </summary>
        /// <param name="value">The decimal value.</param>
        /// <param name="dec">The decimal separator format.</param>
        /// <param name="grp">The group separator format.</param>
        /// <param name="fmt">The format.</param>
        /// <returns>The string representaion.</returns>
        public static string ToString(decimal value, 
            string dec, 
            string grp,
            string fmt)
        {
            return value.ToString(fmt, new NumberFormatInfo
            {
                NumberDecimalSeparator = dec,
                NumberGroupSeparator = grp
            });
        }

        /// <summary>
        /// Converts the string to the decimal value.
        /// </summary>
        /// <param name="s">The string representaion.</param>
        /// <param name="dec">The decimal separator format.</param>
        /// <param name="grp">The group separator format.</param>
        /// <param name="pat">The pattern.</param>
        /// <param name="value">When this methods returns, contains the parsed decimal value.</param>
        /// <returns>true if parsing was successfull; otherwise false.</returns>
        public static bool TryParse(string s, 
            string dec,
            string grp,
            string pat, 
            out decimal value)
        {
            value = Decimal.Zero;
            var m = Regex.Match(s, pat);

            if(!m.Success)
                return false;

            return Decimal.TryParse(m.Value, 
                NumberStyles.Any, 
                new NumberFormatInfo
                {
                    NumberDecimalSeparator = dec,
                    NumberGroupSeparator = grp
                }, 
                out value);
        }

        /// <summary>
        /// Converts the string to the decimal value.
        /// </summary>
        /// <param name="s">The string representaion.</param>
        /// <param name="dec">The decimal separator format.</param>
        /// <param name="grp">The group separator format.</param>
        /// <param name="pat">The pattern.</param>
        /// <returns>Parsed decimal value.</returns>
        public static decimal Parse(string s, string dec, string grp, string pat)
        {
            var m = Regex.Match(s, pat);
            if(!m.Success)
                throw Err.Of<String>().NaN().Ex();
            return Decimal.Parse(m.Value,
                NumberStyles.Any,
                new NumberFormatInfo
                {
                    NumberDecimalSeparator = dec,
                    NumberGroupSeparator = grp
                });
        }

        /// <summary>
        /// Determines whether the provided range is valid.
        /// </summary>
        /// <param name="from">The range "from".</param>
        /// <param name="to">The range "to".</param>
        /// <returns>true if range is valid; otherwise false.</returns>
        public static bool IsRangeValid(decimal? from, decimal? to)
        {
            return !from.HasValue || !to.HasValue || from.Value < to.Value;
        }
    }
}
